#include"cmdtask.h"
#include"token.h"
#include"sqlConnection.h"
#include<mysql/mysql.h>
#pragma pack(1)
char *salt()
{
	const char *charset =
		"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
	const int saltLength = 16;

	char *salt = (char *)malloc((saltLength + 1) * sizeof(char));
	if (!salt) {
		perror("Salt generation failed");
		return NULL;
	}

	for (int i = 0; i < saltLength; i++) {
		salt[i] = charset[rand() % 64]; // 64 是 charset 的长度
	}
	salt[saltLength] = '\0';

	return salt;
}

// 加密密码
char *encryptPassword(const char *password, const char *salt)
{
	char *encryptedPassword = crypt(password, salt);
	if (!encryptedPassword) {
		perror("Password encryption failed");
		return NULL;
	}

	return strdup(encryptedPassword); // 复制返回的密码，避免 `free()` 出错
}

//解析命令中的数据，并存放在map中
int getParameterMap(protocol_client protocol, HashMap *map)
{
	int paraNum = protocol._num;
	char *dataCopy = strdup(protocol._data); // 复制原数据，避免修改
	if (!dataCopy) {
		perror("strdup failed");
		return -1;
	}

	char *array[10] = { 0 };
	char *temp = strtok(dataCopy, "&");
	for (int i = 0; i < paraNum && temp; i++) {
		array[i] = temp;
		temp = strtok(NULL, "&");
	}

	for (int j = 0; j < paraNum; j++) {
		temp = array[j];
		if (!temp)
			continue;

		char *key = strtok(temp, "=");
		char *value = strtok(NULL, "=");

		if (key && value) {
			insert(&map, strdup(key),
			       strdup(value)); // 复制 key 和 value
		}
	}

	free(dataCopy); // 释放复制的数据
	return paraNum;
}

// 拼接key=value数据
int stringCat(char *buf, char *key, char *value)
{
	strcat(buf, key);
	strcat(buf, "=");
	strcat(buf, value);

	return 0;
}

// 初始化 protocol_server 结构体
void initProtocolResponse(protocol_server *res, int status, int length,
			  int flag, const char *data)
{
	res->_status = status;
	res->_length = length;
	res->_flag = flag;
	if (data) {
		snprintf(res->_data, sizeof(res->_data), "%s", data);
	} else {
		res->_data[0] = '\0';
	}
}

// 发送协议响应
int sendProtocolResponse(int netFd, protocol_server *res)
{
	int send_len = sizeof(int) * 4 + res->_length;
	if (send(netFd, &send_len, sizeof(int), MSG_NOSIGNAL) < 0 ||
	    send(netFd, res, send_len, MSG_NOSIGNAL) < 0) {
		perror("send failed");
		return -1;
	}
	return 0;
}

// 处理登录请求
int loginRequest(int netFd, protocol_client protocol, ThreadPool *pthreadpool)
{
	// 获取用户名和密码
	HashMap *map = createHashMap();
	getParameterMap(protocol, map);

	char *username = getKey(map, "username");
	char *password = getKey(map, "password");
    printf("username: %s, password: %s\n", username, password);
	if (!username || !password) {
		printf("Invalid login request: missing username or password\n");
		protocol_server protocol_res;
		initProtocolResponse(&protocol_res, -1, 0, 0, NULL);
		sendProtocolResponse(netFd, &protocol_res);
		return -1;
	}

	printf("InLoginRequest: username: %s, password: %s\n", username, password);

	// 获取数据库连接
	sqlConnection *sqlConnect = getConnection(pthreadpool->_sqlPool);
	if (!sqlConnect) {
		printf("数据库连接池已满，无法获取连接\n");
		return -1;
	}
	printf("成功取出数据库连接\n");

	// 构造查询语句
	char safe_username[256];
	mysql_real_escape_string(&sqlConnect->_connect, safe_username, username,
				 strlen(username));
    printf("safe_username: %s\n", safe_username);
	char bufSql[512];
	snprintf(
		bufSql, sizeof(bufSql),
		"SELECT id, slat, crypt_password FROM user WHERE user_name = '%s'",
		safe_username);

	// 执行查询
	if (mysql_query(&sqlConnect->_connect, bufSql)) {
		fprintf(stderr, "MySQL Query Error: %s\n",
			mysql_error(&sqlConnect->_connect));
		releaseConnection(pthreadpool->_sqlPool, sqlConnect);
		return -1;
	}

	MYSQL_RES *result = mysql_store_result(&sqlConnect->_connect);
	if (!result || mysql_num_rows(result) == 0) {
		// 用户不存在
		protocol_server protocol_res;
		initProtocolResponse(&protocol_res, -1, 0, 0, NULL);
		sendProtocolResponse(netFd, &protocol_res);

		if (result)
			mysql_free_result(result);
		releaseConnection(pthreadpool->_sqlPool, sqlConnect);
		return 0;
	}

	MYSQL_ROW row = mysql_fetch_row(result);
	int userId = atoi(row[0]);
	char *salt = row[1];
	char *dbPassword = row[2];

	// 验证密码
	char *cryptPasswordStr = encryptPassword(password, salt);
    printf("cryptPasswordStr: %s\n", cryptPasswordStr);
	if (strcmp(cryptPasswordStr, dbPassword) != 0) {
		// 密码错误
		protocol_server protocol_res;
		initProtocolResponse(&protocol_res, -1, 0, 0, NULL);
		sendProtocolResponse(netFd, &protocol_res);

		mysql_free_result(result);
		releaseConnection(pthreadpool->_sqlPool, sqlConnect);
		free(cryptPasswordStr);
		return 0;
	}
	free(cryptPasswordStr);

	// 生成 Token
	char bufToken[1024];
	getToken(userId, bufToken, sizeof(bufToken));

    printf("Token: %s\n", bufToken);
	// 返回 Token
	protocol_server protocol_res;
    memset(protocol_res._data, 0, sizeof(protocol_res._data));
    printf("返回TOKEN\n");

    stringCat(protocol_res._data, "token", bufToken);
    protocol_res._length = strlen(protocol_res._data);
    protocol_res._status = 0;
    protocol_res._flag = 1;
    protocol_res._num = 1;

    sendProtocolResponse(netFd, &protocol_res);
    printf("Token 发送成功\n");
    mysql_free_result(result);
    releaseConnection(pthreadpool->_sqlPool, sqlConnect);
    return 0;
}

// 处理用户名注册
int registerNameRequest(int netFd, protocol_client protocol,
			ThreadPool *pthreadpool)
{
	HashMap *map = createHashMap();
	getParameterMap(protocol, map);

	char *username = getKey(map, "username");
	if (!username) {
		printf("Error: username is NULL\n");
		freeHashMap(map);
		return -1;
	}

	printf("need register username is : %s\n", username);

	sqlConnection *sqlConnect = getConnection(pthreadpool->_sqlPool);
	if (!sqlConnect) {
		printf("数据库连接池已满，无法获取连接\n");
		freeHashMap(map);
		return -1;
	}

	char safe_username[256];
	mysql_real_escape_string(&sqlConnect->_connect, safe_username, username,
				 strlen(username));

	char bufSql[512];
	snprintf(bufSql, sizeof(bufSql),
		 "SELECT * FROM user WHERE user_name = '%s'", safe_username);

	if (mysql_query(&sqlConnect->_connect, bufSql) != 0) {
		printf("SQL 查询失败: %s\n",
		       mysql_error(&sqlConnect->_connect));
		releaseConnection(pthreadpool->_sqlPool, sqlConnect);
		freeHashMap(map);
		return -1;
	}

	MYSQL_RES *res = mysql_store_result(&sqlConnect->_connect);
	int userExists = (res && mysql_num_rows(res) > 0);

	protocol_server protocol_res;
	initProtocolResponse(&protocol_res, userExists ? -1 : 0, 0, 0, NULL);
	sendProtocolResponse(netFd, &protocol_res);

	if (res)
		mysql_free_result(res);
	releaseConnection(pthreadpool->_sqlPool, sqlConnect);
	freeHashMap(map);
	return 0;
}

// 处理密码注册
int registerPasswordRequest(int netFd, protocol_client protocol,
			    ThreadPool *pthreadpool)
{
	HashMap *map = createHashMap();
	getParameterMap(protocol, map);

	char *username = getKey(map, "username");
	char *password = getKey(map, "password");
	if (!username || !password) {
		printf("Error: missing username or password\n");
		freeHashMap(map);
		return -1;
	}

	printf("username: %s, password: %s\n", username, password);

	char *saltStr = salt();
	if (!saltStr) {
		freeHashMap(map);
		return -1;
	}

	char *cryptPasswordStr = encryptPassword(password, saltStr);
	if (!cryptPasswordStr) {
		free(saltStr);
		freeHashMap(map);
		return -1;
	}

	sqlConnection *sqlConnect = getConnection(pthreadpool->_sqlPool);
	if (!sqlConnect) {
		free(saltStr);
		free(cryptPasswordStr);
		freeHashMap(map);
		return -1;
	}

	char safe_username[256];
	mysql_real_escape_string(&sqlConnect->_connect, safe_username, username,
				 strlen(username));
    printf("safe_username: %s\n", safe_username);
    printf("saltStr: %s\n", saltStr);
    printf("cryptPasswordStr: %s\n", cryptPasswordStr);
	char bufSql[512];
	snprintf(bufSql, sizeof(bufSql),"INSERT INTO user (user_name, slat, crypt_password) VALUES ('%s', '%s', '%s')",safe_username, saltStr, cryptPasswordStr);

	if (mysql_query(&sqlConnect->_connect, bufSql) != 0) {
		printf("SQL 插入失败: %s\n",
		       mysql_error(&sqlConnect->_connect));
	}
    printf("SQL 插入成功\n");

    //为新用户创建一个根目录
    memset(bufSql, 0, sizeof(bufSql));
    int userId = (int)mysql_insert_id(&sqlConnect->_connect);
    printf("新用户ID: %d\n", userId);
    snprintf(
	    bufSql, sizeof(bufSql),
	    "insert into file(user_id,path,father_path_id,file_type,file_name)VALUES(%d,'/',-1,1,'/')",
	    userId);
    if (mysql_query(&sqlConnect->_connect, bufSql) != 0) {
        printf("SQL 插入根目录失败: %s\n",mysql_error(&sqlConnect->_connect));
    }else{
        printf("userId:%d。SQL 插入根目录成功\n",userId);
    }

    free(cryptPasswordStr);
    free(saltStr);
    freeHashMap(map);

    protocol_server protocol_res;
    initProtocolResponse(&protocol_res, 0, 0, 0, NULL);
    sendProtocolResponse(netFd, &protocol_res);

    releaseConnection(pthreadpool->_sqlPool, sqlConnect);
    return 0;
}

// int main() {
//     // 初始化随机数种子（只需调用一次）
//     srand(time(NULL));

//     // 生成 Salt
//     char *saltStr = salt();
//     if (saltStr == NULL) {
//         return 1;
//     }
//     printf("Generated Salt: %s\n", saltStr);

//     // 加密密码
//     const char *password = "my_password";
//     char *encryptedPassword = encryptPassword(password, saltStr);
//     if (encryptedPassword == NULL) {
//         free(saltStr);
//         return 1;
//     }
//     printf("Encrypted Password: %s\n", encryptedPassword);

//     // 释放内存
//     free(saltStr);

//     return 0;
// }
